package com.dengcj.ecology.mode;

import com.dengcj.util.CjDateTimeUtil;
import com.dengcj.util.CjSqlUtil;
import com.dengcj.util.CjUtil;
import com.dengcj.util.LogCj;
import com.engine.cube.biz.CodeBuilder;
import weaver.conn.RecordSet;
import weaver.conn.RecordSetTrans;
import weaver.formmode.setup.ModeRightInfo;
import weaver.general.BaseBean;
import weaver.general.Util;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author dengchunjie
 * @Description: 表单建模工具类
 * @date 2022/1/10 17:55
 */
public class ModeUtil extends BaseBean {

    LogCj logCj = new LogCj();

    /**
     * 根据查询id和流程字段名获取该字段的fieldid（适用于建模）
     * @param queryPageId
     * @param fieldname
     * @return
     */
    public static String getModeFieldidByQueryPageId(int queryPageId,String fieldname) {
        RecordSet rs = new RecordSet();
        rs.executeQuery("select a.id from workflow_billfield a inner join mode_customsearch b on b.formid=a.billid where b.id=? and a.fieldname=?",queryPageId,fieldname);
        if(rs.next()) {
            return rs.getString("id");
        }

        return "";
    }

    /**
     * 根据查询页面的id获取对应所属模块的id
     * @param queryid
     * @return
     */
    public static int getQueryModeId(int queryid) {
        RecordSet rs = new RecordSet();
        rs.executeQuery("select modeid from mode_customsearch where id=?",queryid);
        if(rs.next()) {
            return rs.getInt("modeid");
        }

        return -1;
    }

    /**
     * 根据模块id获取对应表单的数据库表名
     * @param modeid
     * @return
     */
    public String getTablenameByModeid(int modeid) {
        RecordSet rs = new RecordSet();
        rs.executeQuery("select tablename from workflow_bill a inner join modeinfo b on a.id=b.formid where b.id=?", modeid);
        if(rs.next()) {
            return rs.getString("tablename");
        }

        return "";
    }

    /**
     * 根据表名获取模块Id
     * @param tableName
     * @return
     */
    public int getModeIdByTableName(String tableName){
        RecordSet rs = new RecordSet();
        rs.executeQuery("select b.id from workflow_bill a inner join modeinfo b on a.id=b.formid where a.tablename=?", tableName);
        if(rs.next()){
            return rs.getInt("id");
        }

        return -1;
    }

    /**
     * 根据模块id获取对应表单id
     * @param modeid
     * @return
     */
    public int getFormidByModeid(int modeid) {
        RecordSet rs = new RecordSet();
        rs.executeQuery("select a.id from workflow_bill a inner join modeinfo b on a.id=b.formid where b.id=?", modeid);
        if(rs.next()) {
            return rs.getInt("id");
        }

        return 0;
    }

    /**
     * 根据查询id获取对应表单的数据库表名
     * @param queryid
     * @return
     */
    public String getTablenameByQueryid(int queryid) {
        RecordSet rs = new RecordSet();
        rs.executeQuery("select tablename from workflow_bill a inner join mode_customsearch b on a.id=b.formid where b.id=?", queryid);
        if(rs.next()) {
            return rs.getString("tablename");
        }

        return "";
    }

    /**
     * 记录建模表数据操作日期
     * @param modeid  模块id
     * @param resourceid  数据id
     * @param operatetype  1：新建 2：修改 3：删除 4：查看
     * @return
     */
    public boolean modeDataLog(int modeid,int resourceid,int operatetype,int userid){
        RecordSet rs = new RecordSet();

        //检查operatetype的合法性
        if(operatetype > 4 || operatetype < 1){
            return false;
        }

        String[] operatedesc = new String[]{"新建","修改","删除","查看"};

        CjDateTimeUtil dateTimeUtil = new CjDateTimeUtil();

        String operatedate = dateTimeUtil.getDate();
        String operatetime = dateTimeUtil.getTime();


        Map<String,Object> colsMap = new HashMap<>();

        //relatedid	使用id	integer		否	否	否
        colsMap.put("relatedid",resourceid);

        //relatedname	使用过程	varchar2	1000	否	否	否
        colsMap.put("relatedname","");

        //operatetype	操作类型	integer		否	否	否			1：新建 2：修改 3：删除 4：查看
        colsMap.put("operatetype",operatetype);

        //operatedesc	操作描述	varchar2	4000	是	否	否
        colsMap.put("operatedesc",operatedesc[operatetype-1]);

        //operateuserid	操作人员id	integer		否	否	否
        colsMap.put("operateuserid",userid);

        //operatedate	操作日期	char	10	否	否	否
        colsMap.put("operatedate",operatedate);

        //operatetime	操作时间	char	8	否	否	否
        colsMap.put("operatetime",operatetime);

        //clientaddress	用户ip	varchar2	240	是	否	否
        colsMap.put("clientaddress","");

        String insertSql = CjSqlUtil.getInsertSql("ModeviewLog_"+modeid,colsMap);

        return rs.execute(insertSql);
    }

    /**
     * 新增数据
     * @param creator 创建用户
     * @param tablename 表名
     * @param mainFormFieldMap 主表数据Map
     * @return 新增数据的ID
     */
    public int addMainForm(int creator,String tablename,Map mainFormFieldMap){
        //根据模块ID获取对应数据库表名
        int modeid = getModeIdByTableName(tablename);
        logCj.setLogFileName("addMainForm_Error");
        if(modeid < 0){
            logCj.log("tablename:"+tablename+"获取模块ID失败");
            return -1;
        }
        int formid = getFormidByModeid(modeid);

        RecordSetTrans rst = new RecordSetTrans();
        rst.setAutoCommit(false);
        return addMainForm(creator,modeid,formid,tablename,mainFormFieldMap);
    }

    /**
     * 默认以系统管理员身份新增数据
     * @param tablename 建模表名
     * @param mainFormFieldMap 主表数据Map
     * @return 新增数据的ID
     */
    public int addMainForm(String tablename,Map mainFormFieldMap){
        //根据模块ID获取对应数据库表名
        int modeid = getModeIdByTableName(tablename);
        logCj.setLogFileName("addMainForm_Error");
        if(modeid < 0){
            logCj.log("tablename:"+tablename+"获取模块ID失败");
            return -1;
        }
        int formid = getFormidByModeid(modeid);

        return addMainForm(1,modeid,formid,tablename,mainFormFieldMap);
    }

    /**
     * 新增数据
     * @param creator 创建用户
     * @param tablename 建模表名
     * @param mainFormFieldList 主表数据List
     * @return 新增数据的ID
     */
    public List<Integer> addMainFormBatch(int creator,String tablename,List<Map> mainFormFieldList){
        int modeid = getModeIdByTableName(tablename);
        logCj.setLogFileName("addMainForm_Error");
        if(modeid < 0){
            logCj.log("tablename:"+tablename+"获取模块ID失败");
            return null;
        }
        int formid = getFormidByModeid(modeid);

        return addMainForm(creator,modeid,formid,tablename,mainFormFieldList);
    }

    /**
     * 新增数据
     * 需要在mainFormFieldList中指定for_mode_creator作为数据的创建人
     * @param modeid 所属模块ID
     * @param mainFormFieldList 主表数据List
     * @return 新增数据的ID
     */
    public List<Integer> addMainForm(String creatorKey,int modeid,List<Map> mainFormFieldList){
        //根据模块ID获取对应数据库表名
        String tablename = getTablenameByModeid(modeid);
        logCj.setLogFileName("addMainForm_Error");
        if("".equals(tablename)){
            logCj.log("modeid:"+modeid+"获取表名失败");
            return new ArrayList<>();
        }
        int formid = getFormidByModeid(modeid);

        return addMainForm(creatorKey,modeid,formid,tablename,mainFormFieldList);
    }

    public int addMainForm(int creator,int modeid,int formid,String tablename,Map mainFormFieldMap){
        logCj.setLogFileName("addMainForm_Error");

        int billid = -1;

        CjDateTimeUtil dateTimeUtil = new CjDateTimeUtil();

        //添加建模默认的字段
        mainFormFieldMap.put("formmodeid",modeid);
        mainFormFieldMap.put("modedatacreater",creator);
        mainFormFieldMap.put("modedatacreatertype",0);
        mainFormFieldMap.put("modedatacreatedate",dateTimeUtil.getDate());
        mainFormFieldMap.put("modedatacreatetime",dateTimeUtil.getTime());

        //组装插入SQL
        String insertSql = CjSqlUtil.getInsertSql(tablename,mainFormFieldMap);
        RecordSetTrans rst = new RecordSetTrans();
        rst.setAutoCommit(false);

        try {
            //执行数据库插入
            if (rst.executeSql(insertSql)) {
                String sql = "select max(id) from " + tablename + " where modedatacreater=" + creator + " and formmodeid=" + modeid + " and modedatacreatetime='" + dateTimeUtil.getTime()+"'";

                rst.executeSql(sql);
                rst.next();
                //获取新增数据的id
                billid = rst.getInt(1);

                if (billid > 0){
                    rst.commit();
                    //生成编码字段
                    CodeBuilder cbuild = new CodeBuilder(modeid);
                    cbuild.getModeCodeStr(formid, billid);//生成编号
                    //添加建模权限
                    ModeRightInfo ModeRightInfo = new ModeRightInfo();
                    ModeRightInfo.setNewRight(true);
                    ModeRightInfo.editModeDataShare(creator, modeid, billid);//新建的时候添加共享
                } else {
                    rst.rollback();
                }
            } else {
                logCj.log("SQL执行失败："+insertSql);
            }
        } catch (SQLException sqle){
            logCj.log("SQLException："+sqle.getMessage());
            logCj.log("SQL:"+insertSql);
            rst.rollback();
            logCj.log("Transaction Rollback");
        } catch (Exception e){
            logCj.log(e.getMessage());

            e.printStackTrace();
            rst.rollback();
        }

        return billid;
    }

    public List<Integer> addMainForm(int creator, int modeid, int formid, String tablename, List<Map> mainFormFieldList){
        logCj.setLogFileName("addMainForm_Error");

        CjDateTimeUtil dateTimeUtil = new CjDateTimeUtil();
        RecordSetTrans rst = new RecordSetTrans();
        rst.setAutoCommit(false);

        List<Integer> newIdList = new ArrayList<>();

        int colSize = mainFormFieldList.size();
        for(int i=0; i<colSize ;i++) {
            Map<String, Object> mainFormFieldMap = mainFormFieldList.get(i);

            int billid = -1;
            //添加建模默认的字段
            mainFormFieldMap.put("formmodeid", modeid);
            mainFormFieldMap.put("modedatacreater", creator);
            mainFormFieldMap.put("modedatacreatertype", 0);
            mainFormFieldMap.put("modedatacreatedate", dateTimeUtil.getDate());
            mainFormFieldMap.put("modedatacreatetime", dateTimeUtil.getTime());

            //组装插入SQL
            String insertSql = CjSqlUtil.getInsertSql(tablename, mainFormFieldMap);

            try {
                //执行数据库插入
                if (rst.executeSql(insertSql)) {
                    String sql = "select max(id) from " + tablename + " where modedatacreater=" + creator + " and formmodeid=" + modeid + " and modedatacreatetime='" + dateTimeUtil.getTime() + "'";

                    rst.executeSql(sql);
                    rst.next();
                    //获取新增数据的id
                    billid = rst.getInt(1);

                    if (billid > 0) {
                        newIdList.add(billid);
                    } else {
                        break;
                    }
                } else {
                    logCj.log("SQL执行失败：" + insertSql);
                    break;
                }
            } catch (SQLException sqle) {
                logCj.log("SQLException：" + sqle.getMessage());
                logCj.log("SQL:" + insertSql);
                logCj.log("Transaction Rollback");
                break;
            } catch (Exception e) {
                logCj.log(e.getMessage());
                e.printStackTrace();
                break;
            }
        }

        if(newIdList.size() == colSize){
            rst.commit();
            for(Integer newid : newIdList){
                //生成编码字段
                CodeBuilder cbuild = new CodeBuilder(modeid);
                cbuild.getModeCodeStr(formid, newid);//生成编号
                //添加建模权限
                ModeRightInfo ModeRightInfo = new ModeRightInfo();
                ModeRightInfo.setNewRight(true);
                ModeRightInfo.editModeDataShare(creator, modeid, newid);//新建的时候添加共享
            }
        } else {
            rst.rollback();
            newIdList.clear();
        }

        return newIdList;
    }

    public List<Integer> addMainForm(String creatorKey, int modeid, int formid, String tablename, List<Map> mainFormFieldList){
        logCj.setLogFileName("addMainForm_Error");

        CjDateTimeUtil dateTimeUtil = new CjDateTimeUtil();
        RecordSetTrans rst = new RecordSetTrans();
        rst.setAutoCommit(false);

        List<Integer> newIdList = new ArrayList<>();

        List<Integer> newIdCreatorList = new ArrayList<>();

        int colSize = mainFormFieldList.size();
        for(int i=0; i<colSize ;i++) {
            Map<String, Object> mainFormFieldMap = mainFormFieldList.get(i);

            int creator = Util.getIntValue(Util.null2String(mainFormFieldMap.get(creatorKey)), -1);

            if(creator < 0){
                logCj.log("mainFormFieldMap中未找到"+creatorKey+"的key或者该项的值不合法");
                break;
            }

            int billid = -1;
            //添加建模默认的字段
            mainFormFieldMap.put("formmodeid", modeid);
            mainFormFieldMap.put("modedatacreater", creator);
            mainFormFieldMap.put("modedatacreatertype", 0);
            mainFormFieldMap.put("modedatacreatedate", dateTimeUtil.getDate());
            mainFormFieldMap.put("modedatacreatetime", dateTimeUtil.getTime());

            //组装插入SQL
            String insertSql = CjSqlUtil.getInsertSql(tablename, mainFormFieldMap);

            try {
                //执行数据库插入
                if (rst.executeSql(insertSql)) {
                    String sql = "select max(id) from " + tablename + " where modedatacreater=" + creator + " and formmodeid=" + modeid + " and modedatacreatetime='" + dateTimeUtil.getTime() + "'";

                    rst.executeSql(sql);
                    rst.next();
                    //获取新增数据的id
                    billid = rst.getInt(1);

                    if (billid > 0) {
                        newIdList.add(billid);
                        newIdCreatorList.add(creator);
                    } else {
                        break;
                    }
                } else {
                    logCj.log("SQL执行失败：" + insertSql);
                    break;
                }
            } catch (SQLException sqle) {
                logCj.log("SQLException：" + sqle.getMessage());
                logCj.log("SQL:" + insertSql);
                logCj.log("Transaction Rollback");
                break;
            } catch (Exception e) {
                logCj.log(e.getMessage());
                e.printStackTrace();
                break;
            }
        }

        int newIdListSize = newIdList.size();
        if(newIdListSize == colSize){
            rst.commit();
            for(int i=0;i<newIdListSize;i++){
                int newid = newIdList.get(i);
                int creator = newIdCreatorList.get(i);
                //生成编码字段
                CodeBuilder cbuild = new CodeBuilder(modeid);
                cbuild.getModeCodeStr(formid, newid);//生成编号
                //添加建模权限
                ModeRightInfo ModeRightInfo = new ModeRightInfo();
                ModeRightInfo.setNewRight(true);
                ModeRightInfo.editModeDataShare(creator, modeid, newid);//新建的时候添加共享
            }
        } else {
            newIdList.clear();
            rst.rollback();
        }

        return newIdList;
    }


    /**
     * 删除模块数据
     * @param userid 对应操作者
     * @param modeid 模块数据
     * @param billid 需要删除的数据
     * @return 返回操作结果
     */
    public boolean delete(int userid,int modeid,int billid){
        boolean flag = false;

        //根据模块ID获取对应数据库表名
        String tablename = getTablenameByModeid(modeid);
        RecordSetTrans rst = new RecordSetTrans();
        rst.setAutoCommit(false);
        try {
            //删除数据
            flag = rst.execute("delete from " + tablename + " where id=" + billid);

            if(flag){

                //删除权限
                flag = rst.execute("delete from modedatashare_" + modeid + " where sourceid=" + billid);
                flag = rst.execute("delete from modedatashare_" + modeid + "_set where sourceid=" + billid);
                if(modeDataLog(modeid,billid,3,userid)){
                    rst.commit();
                } else {
                    rst.rollback();
                    flag = false;
                }
            }
        }catch (Exception e){
            rst.rollback();
            e.printStackTrace();
        }


        return flag;
    }
}
